package com.pianzhu.blockchainemr.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;

@Slf4j
public class JWTUtils {
    private static final String SECRET_KEY_STRING = "ILOVEYOUILOVEYOUILOVEYOUILOVEYOU"; // 需要至少32字符用于HS512
    private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(SECRET_KEY_STRING.getBytes());
    private static final Long EXPIRATION_TIME = 1000L * 60 * 60 * 12; // 过期时间 12 hours

    /**
     * 生成token
     * @param claims 自定义的声明
     * @return token
     */
    public static String createJWT(Map<String, Object> claims) {
        try {
            String token = Jwts.builder()
                    .claims(claims) // 新版设置claims的方式
                    .issuedAt(new Date()) // 添加签发时间
                    .expiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                    .signWith(SECRET_KEY, Jwts.SIG.HS256) // 新版签名方式
                    .compact();
            log.info("生成token：{}", token);
            return token;
        } catch (JwtException e) {
            throw new RuntimeException("Failed to create JWT", e);
        }
    }

    /**
     * 解析token
     * @param token token
     * @return 自定义的声明
     */
    public static Claims parseJWT(String token) {
        try {
            return Jwts.parser()
                    .verifyWith(SECRET_KEY) // 新版验证方式
                    .build()
                    .parseSignedClaims(token) // 新版解析方法
                    .getPayload();
        } catch (JwtException e) {
            throw new RuntimeException("JWT解析失败", e);
        }
    }

    /**
     * 验证token是否有效
     * @param token token
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        try {
            parseJWT(token);
            return true;
        } catch (JwtException e) {
            return false;
        }
    }

    /**
     * 从token中获取用户ID
     * @param token token
     * @return 用户ID
     */
    public static Integer getUserIdFromToken(String token) {
        Claims claims = parseJWT(token);
        return claims.get("id", Integer.class);
    }

    /**
     * 从token中获取用户名
     * @param token token
     * @return 用户名
     */
    public static String getUsernameFromToken(String token) {
        Claims claims = parseJWT(token);
        return claims.get("username", String.class);
    }

    /**
     * 检查token是否过期
     * @param token token
     * @return 是否过期
     */
    public static boolean isTokenExpired(String token) {
        Claims claims = parseJWT(token);
        return claims.getExpiration().before(new Date());
    }
}